package manager

import (
	"dragonfly/common/config"
	"dragonfly/common/log"
	"dragonfly/common/tcp"
	"dragonfly/common/types"
	"fmt"
	"github.com/rs/zerolog"
	"time"
)

type Manager struct {
	*tcp.AsyncTCPServer
	hostinfo   *types.Host
	settings   *config.ManagerSettings
	log        *zerolog.Logger
	agentQueue []*tcp.TCPConn
}

var (
	manager Manager
)

func InitManager(cfg *config.Config) error {
	protocol := &tcp.DefaultProtocol{}
	protocol.SetMaxPacketSize(0)
	s := tcp.NewAsyncTCPServer(
		*cfg.ManagerSettings.ListenAddress,
		&callback{},
		protocol,
	)

	manager = Manager{
		s,
		&types.Host{Name: "manager"},
		&cfg.ManagerSettings,
		log.NewLogger(&cfg.LogSettings),
		[]*tcp.TCPConn{},
	}

	return manager.ListenAndServe()
}

func (this *Manager) dialAgent() error {
	for _, agentConn := range this.agentQueue {
		if !agentConn.IsClosed() {
			return fmt.Errorf("agent is already connected")
		}
	}

	conn, err := this.Connect("192.168.80.128:10001", nil, nil)
	if err != nil {
		return err
	}
	this.agentQueue = append(this.agentQueue, conn)

	return nil
}

func (this *Manager) getHeartbeat() {
	heartbeat_t := time.NewTicker(time.Second * 2)
	pkt := tcp.NewDefaultPacket(
		types.MsgGetHeartbeat,
		this.hostinfo.Encode(),
	)
	for _, agentConn := range this.agentQueue {
		manager.log.Debug().Msgf(
			"get heartbeat from agent %v",
			agentConn.GetRemoteIPAddress(),
		)
		if err := agentConn.AsyncWritePacket(pkt); err != nil {
			this.log.Error().Msg("get heartbeat failed")
		}

		for {
			select {
			case <-heartbeat_t.C:
				if err := agentConn.AsyncWritePacket(pkt); err != nil {
					this.log.Error().Msg("get heartbeat failed")
				}
			}
		}
	}
}

func (this *Manager) StartTask() {
	go this.getHeartbeat()
}
